#pragma once 
#include <memory>
#include <functional>
#include "fields.hpp"

namespace yssrpc
{
    // 消息类型的抽象
    class BaseMessage {
        public:
            using ptr = std::shared_ptr<BaseMessage>;
            virtual ~BaseMessage(){}
            virtual void setId(const std::string &id) {
                _rid = id;
            }
            virtual std::string rid() { return _rid; }
            virtual void setMType(MType mtype) {
                _mtype = mtype;
            }
            virtual MType mtype() { return _mtype; }
            virtual std::string serialize() = 0;
            virtual bool unserialize(const std::string &msg) = 0;
            virtual bool check() = 0; // 检查消息的字段是否完整
        private:
            MType _mtype; // 消息类型
            std::string _rid; // 消息编号
    };

    // 缓冲区的抽象
    class BaseBuffer {
        public:
            using ptr = std::shared_ptr<BaseBuffer>; 
            virtual size_t readableSize() = 0; // 返回当前缓冲区有多少数据
            virtual int32_t peekInt32() = 0; // 从缓冲区取出4字节的数据
            virtual void retrieveInt32() = 0; // 从缓冲区删除4字节的数据
            virtual int32_t readInt32() = 0; // 取出并删除4字节的数据
            virtual std::string retrieveAsString(size_t len) = 0; // 根据len取出数据
    };

    // 协议层的抽象
    class BaseProtocol {
        public:
            using ptr = std::shared_ptr<BaseProtocol>;
            // 是否能够处理
            virtual bool canProcessed(const BaseBuffer::ptr &buf) = 0;
            // 能处理返回消息
            virtual bool onMessage(const BaseBuffer::ptr &buf, BaseMessage::ptr &msg) = 0;
            // 对消息进行序列化
            virtual std::string serialize(const BaseMessage::ptr &msg) = 0;
    };

    // 通信连接的抽象 
    class BaseConnection {
        public:
            using ptr = std::shared_ptr<BaseConnection>;
            virtual void send(const BaseMessage::ptr &msg) = 0; // 发送消息
            virtual void shutdown() = 0; // 关闭连接
            virtual bool connected() = 0; // 判断连接是否正常
    };

    // 服务端的抽象
    using ConnectionCallback = std::function<void(const BaseConnection::ptr&)>;
    using CloseCallback = std::function<void(const BaseConnection::ptr&)>;
    using MessageCallback = std::function<void(const BaseConnection::ptr&, BaseMessage::ptr&)>;
    class BaseServer {
        public:
            using ptr = std::shared_ptr<BaseServer>;
            virtual void setConnectionCallback(const ConnectionCallback& cb) {
                _cb_connection = cb;
            }
            virtual void setCloseCallback(const CloseCallback& cb) {
                _cb_close = cb;
            }
            virtual void setMessageCallback(const MessageCallback& cb) {
                _cb_message = cb;
            }
            virtual void start() = 0; // 启动服务
        protected:
            ConnectionCallback _cb_connection; // 连接回调
            CloseCallback _cb_close; // 关闭连接回调
            MessageCallback _cb_message; // 消息处理回调
    };

    // 客户端的抽象
    class BaseClient {
        public:
            using ptr = std::shared_ptr<BaseClient>;
            virtual void setConnectionCallback(const ConnectionCallback& cb) {
                _cb_connection = cb;
            }
            virtual void setCloseCallback(const CloseCallback& cb) {
                _cb_close = cb;
            }
            virtual void setMessageCallback(const MessageCallback& cb) {
                _cb_message = cb;
            }
            virtual void connect() = 0; // 连接
            virtual void shutdown() = 0; // 关闭连接
            virtual bool send(const BaseMessage::ptr&) = 0; // 发送数据
            virtual BaseConnection::ptr connection() = 0; // 获取连接
            virtual bool connected() = 0; // 判断连接是否正常
        protected:
            ConnectionCallback _cb_connection; // 连接回调
            CloseCallback _cb_close; // 关闭连接回调
            MessageCallback _cb_message; // 消息处理回调
    };
}